using System;
using System.Collections.Generic;
using System.Security.Principal;
using System.Text;
using System.Threading;
using Sedna.API.Security;
using Sedna.API.Session;
using Sedna.API.Support;
using Sedna.Core;
using Sedna.Domain;
using Spring.Objects.Factory;

namespace Sedna.API.Session
{
    public class SessionManager: ISessionManager, IInitializingObject
    {


//        private IDictionary<IToken, ISession> sessions;
        private ITokenizer tokenizer;
        private IPrincipalInjector principalInjector;
        private SessionTracker sessionTracker;
        private int timeout = 60;
        private string sessionKeySlot = "sedna-api-session-key";

        public string SessionKeySlot
        {
            set { sessionKeySlot = value; }
        }

        public int Timeout
        {
            set { timeout = value; }
        }

        public ITokenizer Tokenizer
        {
            set { tokenizer = value; }
        }

        
        public IToken CurrentSessionKey
        {
            get { return (IToken)Thread.GetData(Thread.GetNamedDataSlot(sessionKeySlot)); }
            set 
            {
                ISession session = sessionTracker.Get(value);
                if (session == null)
                {
                    throw new SednaException(SednaExceptionCodes.NotAuthenticated, "You are not logged in!");
                }
                principalInjector.InjectPrincipal(session.Principal);
                Thread.SetData(Thread.GetNamedDataSlot(sessionKeySlot), value);
            }
        }

        public ISession CurrentSession
        {
            get { return sessionTracker.Get(CurrentSessionKey); }
        }
        
        public IPrincipalInjector PrincipalInjector
        {
            set { principalInjector = value; }
        }

//        public SessionManager()
//        {
////            sessions = new Dictionary<IToken, ISession>();
//        }

        public void AfterPropertiesSet()
        {
            sessionTracker = new SessionTracker(new TimeSpan(0, 0, timeout));
            sessionTracker.StartTracking();
        }

        ~SessionManager()
        {
            sessionTracker.StopTracking();
        }

        public ISession CreateSession(IPrincipal principal)
        {
            ISession session = new Session(principal, tokenizer.GenerateToken(principal));
            sessionTracker.Add(session);
            return session;
        }

        public void DestroySession(IToken sessionKey)
        {
            sessionTracker.Remove(sessionKey);
        }

        public ISession GetSession(IToken sessionKey)
        {
            return sessionTracker.Get(sessionKey);   
        }

    }
}

